import java.net.*;
import java.io.*;
import java.io.File;
import java.lang.management.ClassLoadingMXBean;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
import java.lang.management.RuntimeMXBean;
import java.lang.management.ThreadMXBean;
import java.util.*;

import com.sun.management.OperatingSystemMXBean;
public class Server{
    public static void main(String[] args){
        try{
            int serverPort = 7896;
            ServerSocket listenSocket = new ServerSocket(serverPort);
            while(true){
                Socket clientSocket = listenSocket.accept();
                Connection c = new Connection(clientSocket);
            }
        }catch(IOException e){
            System.out.println("Listen " + e.getMessage());
        }
    }
}

class Connection extends Thread{
    DataInputStream in;
    DataOutputStream out;
    Socket clientSocket;
    public Connection(Socket aClientSocket){
        try{
            clientSocket = aClientSocket;
            in = new DataInputStream(clientSocket.getInputStream());
            out = new DataOutputStream(clientSocket.getOutputStream());
            this.start();
        }catch(IOException e){
            System.out.println("Connection " + e.getMessage());
        }
    }
    public void run(){
        try{
            String data = in.readUTF();
            StringTokenizer tokens = new StringTokenizer( data, "\n" );
            int requestid=0;
            String Msg="";
            String res="";
            for( int x = 1; tokens.hasMoreElements(); x++ )
            {

                String tmp =  tokens.nextToken();
                StringTokenizer tokens2 = new StringTokenizer(tmp , "=" );
                tokens2.hasMoreElements(); 
                String var1=  tokens2.nextToken();
                tokens2.hasMoreElements(); 
                String var2=  tokens2.nextToken();
                System.out.println(var1);
                if(var1.equals("requestid")){
                    requestid = Integer.parseInt(var2);
                }

                if(var1.equals("messagename")){
                    if(var2.equals("cpu")){
                        //res = Cpu();
                        res = "cpu";
                    }
                    if(var2.equals("mem")){
                        res = Mem();
                    }
                    if(var2.equals("disk")){
                        res = Disk();
                    }
                }
            }
            Msg = "messagetype=rep\nrequestid="+requestid + "\nres=" + res;
            //out.writeUTF(data);
            out.writeUTF(Msg);
        }catch(EOFException e){
            System.out.println("EOF: " + e.getMessage());
        }catch(IOException e){
            System.out.println("IO: " + e.getMessage());
        }finally{
            try{
                clientSocket.close();
            }catch(IOException e){}
        }
    }

    public String Mem(){
        MemoryMXBean membean = (MemoryMXBean)ManagementFactory.getMemoryMXBean();
        MemoryUsage heap = membean.getHeapMemoryUsage();
        System.out.println("Heap Memory: " + heap.toString());

        MemoryUsage nonheap = membean.getNonHeapMemoryUsage();
        System.out.println("NonHeap Memory: " + nonheap.toString());

        return "Heap Memory : " + heap.toString() + ", NonHeap Memory : " + nonheap.toString();
    }

    public String Cpu(){
        OperatingSystemMXBean osbean = (OperatingSystemMXBean)ManagementFactory.getOperatingSystemMXBean();
        RuntimeMXBean runbean = (RuntimeMXBean) ManagementFactory.getRuntimeMXBean();

        long bfprocesstime =osbean.getProcessCpuTime();
        long bfuptime = runbean.getUptime();
        long ncpus = osbean.getAvailableProcessors();

        for (int i =0;  i<1000000; ++i)
        {
            ncpus = osbean.getAvailableProcessors();
        }

        long afprocesstime =osbean.getProcessCpuTime();
        long afuptime = runbean.getUptime();

        float cal = (afprocesstime-bfprocesstime)/((afuptime-bfuptime)*10000f);

        float usage = Math.min(99f, cal);

        //System.out.println("Calculation: " + cal);
        //System.out.println("CPU Usage: " + usage);
        return "Calculation: " + cal + ", CPU usage: " + usage;

    }

    public String Disk(){
        File root = null;

        try{
            root = new File("D:/");

            System.out.println("Total  Space: " + root.getTotalSpace());
            System.out.println("Usable Space: " + root.getUsableSpace());

        }catch(Exception e){e.printStackTrace();}
        return "Total Space: " + root.getTotalSpace() + ", Usable Space: " + root.getUsableSpace();
    }

}

